package com.black.cat.config;

import com.black.cat.bean.ConfigurableBeanFactory;
import com.black.cat.core.AttributeAccessor;
import com.black.cat.core.BeanMetadataElement;
import com.black.cat.lang.Nullable;

/**
 * Spring对bean的抽象    定义了bean的基本行为    xml解析的内容封装在GenericBeanDefinition
 */
public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement {


    /**
     *单例常量,来自bean的scope属性
     */
    String SCOPE_SINGLETON = ConfigurableBeanFactory.SCOPE_SINGLETON;

    /**
     *原型常量,来自bean的scope属性
     */
    String SCOPE_PROTOTYPE = ConfigurableBeanFactory.SCOPE_PROTOTYPE;


    //Bean角色的常量
    //APPLICATION:用户
    int ROLE_APPLICATION = 0;
    //SUPPORT:某些复杂配置的一部分
    int ROLE_SUPPORT = 1;
    //INFRASTRUCTURE:完全内部使用，与用户无关
    int ROLE_INFRASTRUCTURE = 2;


    //  <beans>
// <bean id="parentBean">
//     <property name="name"><value>parent</value></property>
//     <property name="age"><value>1</value></property>
// </bean>
// <bean id="sonBean" class="SonBean"
//					parent="parentBean" init-method="initialize">
//     <property name="name"><value>override</value></property>
// </bean>
    //bean定义对象的父类定义对象名称
    void setParentName(@Nullable String parentName);

    @Nullable
    String getParentName();

    //bean对象的实际class类
    void setBeanClassName(@Nullable String beanClassName);

    @Nullable
    String getBeanClassName();

    //bean对象的scope<singleton或者prototype>
    void setScope(@Nullable String scope);

    @Nullable
    String getScope();

    //是否懒加载
    void setLazyInit(boolean lazyInit);


    boolean isLazyInit();

    //设置依赖的bean对象，被依赖的bean对象总是会比当前bean对象先创建
    void setDependsOn(@Nullable String... dependsOn);
    @Nullable
    String[] getDependsOn();

    //设置是否可以自动注入。只对@Autowired注解有效，配置文件中可以通过property显示注入
    void setAutowireCandidate(boolean autowireCandidate);

    boolean isAutowireCandidate();

    //TODO   待详细了解
    //配置bean为主要候选bean。当同一个接口的多个实现类或者一个类多次注入到spring容器时，通过该属性来配置     //某个bean为主候选bean，通过类型来注入时，默认为使用主候选bean注入
    void setPrimary(boolean primary);

    boolean isPrimary();


    //设置创建bean的工厂名称
    void setFactoryBeanName(@Nullable String factoryBeanName);

    @Nullable
    String getFactoryBeanName();

    //设置创建bean的工厂中，创建bean的具体方法
    void setFactoryMethodName(@Nullable String factoryMethodName);

    @Nullable
    String getFactoryMethodName();

    //记录构造函数注入属性，通过bean的水性constructor-arg来注入
    ConstructorArgumentValues getConstructorArgumentValues();


    default boolean hasConstructorArgumentValues() {
        return !getConstructorArgumentValues().isEmpty();
    }

    //普通属性集合
    MutablePropertyValues getPropertyValues();


    default boolean hasPropertyValues() {
        return !getPropertyValues().isEmpty();
    }

    //设置创建bean时，默认初始化的方法
    void setInitMethodName(@Nullable String initMethodName);

    @Nullable
    String getInitMethodName();

    //设置销毁bean时调用的方法名称。注意需要调用context的close()方法才会调用
    void setDestroyMethodName(@Nullable String destroyMethodName);
    @Nullable
    String getDestroyMethodName();

    //设置bean的分类。
    //APPLICATION:用户
    //INFRASTRUCTURE:完全内部使用，与用户无关
    //SUPPORT:某些复杂配置的一部分
    void setRole(int role);


    int getRole();

    //对bean对象的描述
    void setDescription(@Nullable String description);

    @Nullable
    String getDescription();


    //是否是单例
    boolean isSingleton();

    //是否是原型
    boolean isPrototype();
    //是否是抽象
    boolean isAbstract();

    //Resource 的描述
    @Nullable
    String getResourceDescription();

    //获取原始的beanDefinition
    @Nullable
    BeanDefinition getOriginatingBeanDefinition();


}
